package com.boarsoft.boar.agent.client;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Lazy;

import com.boarsoft.agent.AgentService;
import com.boarsoft.bean.ReplyInfo;
import com.boarsoft.boar.agent.client.pojo.Operation;
import com.boarsoft.common.Util;
import com.boarsoft.rpc.core.RpcContext;

/**
 * Linux操作系统下服务控制器
 * 
 * @author YangLiu
 * @CreateDate 2018年3月27日 下午5:39:13
 * @version 1.0
 * 
 * @UpdateUser 修改人名称
 * @UpdateDate 2018年3月27日 下午5:39:13
 * @UpdateRemark 修改具体的内容
 */
public abstract class LinuxController<T> implements ServiceController<T> {
	
	private static final Logger logger = LoggerFactory.getLogger(LinuxController.class);
	
	//TODO 改为针对每个shell文件的配置
	protected boolean canSSH = true;
	
	protected String agentPort = "9901";
	
	@Autowired
	@Lazy
	@Qualifier("agentC")
	protected AgentService agentC;
	
	@Autowired
	@Lazy
	@Qualifier("agentX")
	protected AgentService agentX;

	@SuppressWarnings("unchecked")
	@Override
	public ReplyInfo<T> start(Operation opt) {
		
		ReplyInfo<T> reply = null;
		String agentAddress = null;
		try {
			if (canSSH) {
				// 如果指定采用打包服务器上的agent服务进行远程操作，则优先使用指定的地址的agent服务，如果没有指定则在注册中心范围内自动选取
				if (Util.strIsNotEmpty(opt.getAgentAddress())) {
					agentAddress = opt.getAgentAddress();
					RpcContext.specify2(agentAddress);
				}
				reply = (ReplyInfo<T>) agentC.executeShell(opt.getSvrUser(), 
						opt.getSvrAddress(),
						opt.getProxyAbsPath(),
						opt.getProxyRelPath(), 
						new String[]{opt.getTargetAbsPath(), opt.getTargetName(), opt.getRunParamsStr()}, 
						opt.getOperator());
			} else {
				// 如果指定采用应用服务器上的agent服务进行本地操作，则以应用服务器地址作为agent服务地址，端口使用配置指定的端口
				agentAddress = String.format("%s:%s", opt.getSvrAddress(), agentPort);
				RpcContext.specify2(agentAddress);
				reply = (ReplyInfo<T>) agentC.executeShell(opt.getProxyAbsPath(),
						opt.getProxyRelPath(), 
						new String[]{opt.getTargetAbsPath(), opt.getTargetName(), opt.getRunParamsStr()}, 
						opt.getOperator());
			}
		} catch(Exception e) {
			logger.error("Error to call agent service by RPC.", e);
			reply = new ReplyInfo<T>(false, null);
		} finally {
			if (Util.strIsNotEmpty(agentAddress)) {
				RpcContext.specify2(null);
			}
		}
		return reply;
	}

	public boolean isCanSSH() {
		return canSSH;
	}

	public void setCanSSH(boolean canSSH) {
		this.canSSH = canSSH;
	}

	public String getAgentPort() {
		return agentPort;
	}

	public void setAgentPort(String agentPort) {
		this.agentPort = agentPort;
	}

}
